package com.chuangjiangx.member.manager.web.web.stored.controller;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.DateUtils;
import com.chuangjiangx.commons.PageUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.commons.request.Page;
import com.chuangjiangx.commons.response.Response;
import com.chuangjiangx.commons.response.ResponseUtils;
import com.chuangjiangx.member.manager.basic.web.controller.BaseController;
import com.chuangjiangx.member.manager.basic.web.interceptor.Login;
import com.chuangjiangx.member.manager.common.Constants;
import com.chuangjiangx.member.manager.common.RequestHeadersUtil;
import com.chuangjiangx.member.manager.common.ThreadLocalUser;
import com.chuangjiangx.member.manager.common.utils.StrUtils;
import com.chuangjiangx.member.manager.web.web.score.response.ScoreFormDetailListResponse;
import com.chuangjiangx.member.manager.web.web.stored.request.QueryStoredRequest;
import com.chuangjiangx.member.manager.web.web.stored.request.StoredDetailListFormRequest;
import com.chuangjiangx.member.manager.web.web.stored.request.StoredDetailListFormStoreRequest;
import com.chuangjiangx.member.manager.web.web.stored.response.StoredAmountResponse;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryStoredCondition;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryStoredListForMerchantCondition;
import com.chuangjiangx.member.stored.ddd.query.MbrStoredStreamQuery;
import com.chuangjiangx.member.stored.ddd.query.dto.StoredAmountDTO;
import com.chuangjiangx.member.stored.ddd.query.dto.StoredDetailListForMerchantDTO;
import com.sun.jmx.snmp.ThreadContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 储值明细报表
 */
@RestController
@RequestMapping(value = "/api/mbr/storedDetailForm", produces = "application/json")
public class MbrStoredStreamFormController extends BaseController {
    @Autowired
    private MbrStoredStreamQuery mbrStoredStreamQuery;


    /**
     * 储值明细列表--商户权限
     *
     * @param request 请求参数
     * @return 列表
     * @map storedListForm
     * @see ScoreFormDetailListResponse
     */
    @RequestMapping(value = "/searchStoredlist")
    @Login
    public Response searchStoredListForm(@RequestBody @Validated StoredDetailListFormRequest request) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryStoredListForMerchantCondition condition = new QueryStoredListForMerchantCondition();
        BeanUtils.copyProperties(request, condition);
        PageUtils.copyPage(condition, request.getPage());
        condition.setMerchantId(user.getMerchantId());
        condition.setEndTime(condition.getEndTime() == null ? null : DateUtils.addDate(condition.getEndTime()));

        PagingResult<StoredDetailListForMerchantDTO> dtoPagingResult = mbrStoredStreamQuery.searchStoredListMerchant(condition);
        List<ScoreFormDetailListResponse> respList = CJBeanUtils
                .convertCollection(dtoPagingResult.getItems(), ScoreFormDetailListResponse.class, (source, target) -> {
                    if (target.getOperationUser() == null) {
                        target.setOperationUser(user.getMerchantName());
                    }
                    target.setMobile(StrUtils.encodeMobilePhone(source.getMobile()));
                });

        return ResponseUtils.successPage(request.getPage(), dtoPagingResult, "storedListForm", respList);
    }


    /**
     * 储值明细列表--商户权限 导出
     */
    @RequestMapping(value = "/export/searchStoredlist", produces = "application/json")
    @Login
    public void exportSearchStoredListForm(HttpServletResponse response, HttpServletRequest request, HttpSession session) throws IOException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String mobile = request.getParameter("mobile");
        String type = request.getParameter("type");
        String storeName = request.getParameter("storeName");
        String terminalType = request.getParameter("terminalType");
        String pageNo = request.getParameter("pageNO");
        StoredDetailListFormRequest param = new StoredDetailListFormRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }
        if (!"".equals(mobile)) {
            param.setMobile(mobile);
        }
        if (!"".equals(type)) {
            param.setType(Byte.valueOf(type));
        }
        if (!"".equals(storeName)) {
            param.setStoreName(storeName);
        }
        if (!"".equals(terminalType)) {
            param.setPayTerminal(Byte.valueOf(terminalType));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "储值明细列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<ScoreFormDetailListResponse> list = getExportSearchStoredListForm(param, session);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            getExportSearchStoredlistData(sdf, bw, list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
            }
            if (osw != null) {
                osw.close();
            }
            if (out != null) {
                out.close();
            }
        }

    }

    private List<ScoreFormDetailListResponse> getExportSearchStoredListForm(@RequestBody @Validated StoredDetailListFormRequest request, HttpSession session) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryStoredListForMerchantCondition condition = new QueryStoredListForMerchantCondition();
        BeanUtils.copyProperties(request, condition);
        PageUtils.copyPage(condition, request.getPage());
        condition.setMerchantId(user.getMerchantId());
        condition.setEndTime(condition.getEndTime() == null ? null : DateUtils.addDate(condition.getEndTime()));

        List<ScoreFormDetailListResponse> listR = getScoreFormDetailListResponses(condition);

        return listR;
    }

    /**
     * 储值明细列表--门店权限
     *
     * @param request 请求参数
     * @param session 获取用户信息session
     * @return 列表
     * @map storedListForm
     * @see ScoreFormDetailListResponse
     */
    @RequestMapping(value = "/searchStoredlistForStore")
    @Login
    public Response searchStoredlistForStore(@RequestBody @Validated StoredDetailListFormStoreRequest request, HttpSession session) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryStoredListForMerchantCondition condition = new QueryStoredListForMerchantCondition();
        BeanUtils.copyProperties(request, condition);
        PageUtils.copyPage(condition, request.getPage());
        condition.setMerchantId(user.getMerchantId());
        condition.setStoreId(user.getStoreId());
        condition.setEndTime(condition.getEndTime() == null ? null : DateUtils.addDate(condition.getEndTime()));

        PagingResult<StoredDetailListForMerchantDTO> dtoPagingResult = mbrStoredStreamQuery.searchStoredListMerchant(condition);
        List<ScoreFormDetailListResponse> respList = CJBeanUtils
                .convertCollection(dtoPagingResult.getItems(), ScoreFormDetailListResponse.class,(source, target) -> {
                    target.setMobile(StrUtils.encodeMobilePhone(source.getMobile()));
                });

        return ResponseUtils.successPage(request.getPage(), dtoPagingResult, "storedListForm", respList);
    }


    /**
     * 储值明细列表--门店权限 导出
     */
    @RequestMapping(value = "/export/searchStoredlistForStore")
    @Login
    public void exportSearchStoredlistForStore(HttpServletResponse response, HttpServletRequest request) throws ParseException, IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String mobile = request.getParameter("mobile");
        String type = request.getParameter("type");
        String storeName = request.getParameter("storeName");
        String terminalType = request.getParameter("terminalType");
        String pageNo = request.getParameter("pageNO");
        StoredDetailListFormStoreRequest param = new StoredDetailListFormStoreRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }
        if (!"".equals(mobile)) {
            param.setMobile(mobile);
        }
        if (!"".equals(type)) {
            param.setType(Byte.valueOf(type));
        }
        if (!"".equals(storeName)) {
            param.setStoreName(storeName);
        }
        if (!"".equals(terminalType)) {
            param.setPayTerminal(Byte.valueOf(terminalType));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "储值明细列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<ScoreFormDetailListResponse> list = getExportSearchStoredlistForStore(param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            getExportSearchStoredlistData(sdf, bw, list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
            }
            if (osw != null) {
                osw.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    private void getExportSearchStoredlistData(SimpleDateFormat sdf, BufferedWriter bw, List<ScoreFormDetailListResponse> list) throws IOException {
        list.forEach(scoreFormDetailListResponse -> {
            if (StringUtils.isNotBlank(scoreFormDetailListResponse.getMobile())) {
                scoreFormDetailListResponse.setMobile(StrUtils.encodeMobilePhone(scoreFormDetailListResponse.getMobile()));
            }
        });
        bw.append("序号").append(",")
                .append("交易单号").append(",")
                .append("交易时间").append(",")
                .append("手机号码").append(",")
                .append("交易类型").append(",")
                .append("交易金额").append(",")
                .append("赠送金额").append(",")
                .append("交易后余额").append(",")
                .append("支付方式").append(",")
                .append("\r");

        if (list != null && !list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) {
                ScoreFormDetailListResponse data = list.get(i);
                String dateTime = null;
                if (data.getDateTime() != null) {
                    dateTime = sdf.format(data.getDateTime());
                }
                bw.append(String.valueOf(i + 1)).append(",")
                        .append(data.getStoredNum() == null ? "" : String.valueOf(getCompleteExcelString(data.getStoredNum()))).append(",")
                        .append(dateTime == null ? "" : dateTime).append(",")
                        .append(data.getMobile() == null ? "" : data.getMobile()).append(",")
                        .append(data.getTypeText() == null ? "" : data.getTypeText()).append(",")
                        .append(data.getTransactionAmount() == null ? "" : data.getTransactionAmount().toString()).append(",")
                        .append(data.getGiftAmount() == null ? "" : data.getGiftAmount().toString()).append(",")
                        .append(data.getPostTradingBalance() == null ? "" : data.getPostTradingBalance().toString()).append(",")
                        .append(data.getPayTypeText() == null ? "" : data.getPayTypeText()).append(",")
                        .append("\r");
            }
        }
    }

    private List<ScoreFormDetailListResponse> getExportSearchStoredlistForStore(@RequestBody @Validated StoredDetailListFormStoreRequest request) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryStoredListForMerchantCondition condition = new QueryStoredListForMerchantCondition();
        BeanUtils.copyProperties(request, condition);
        PageUtils.copyPage(condition, request.getPage());
        condition.setMerchantId(user.getMerchantId());
        condition.setStoreId(user.getStoreId());
        condition.setEndTime(condition.getEndTime() == null ? null : DateUtils.addDate(condition.getEndTime()));

        List<ScoreFormDetailListResponse> listR = getScoreFormDetailListResponses(condition);
        return listR;
    }

    /**
     * 获取Excel输出结果
     * @param condition
     * @return
     */
    private List<ScoreFormDetailListResponse> getScoreFormDetailListResponses(QueryStoredListForMerchantCondition condition) {
        List<ScoreFormDetailListResponse> listScoreExcel = new ArrayList<ScoreFormDetailListResponse>();
        if (condition.getStartTime() == null || condition.getEndTime() == null) {
            if (condition.getMobile() != null || condition.getType() != null || condition.getPayTerminal() != null || condition.getStoreName() != null) {
                PagingResult<StoredDetailListForMerchantDTO> dtoPagingResult = mbrStoredStreamQuery.searchStoredListMerchant(condition);
                listScoreExcel = CJBeanUtils.convertCollection(dtoPagingResult.getItems(), ScoreFormDetailListResponse.class);
            } else {
                List<StoredDetailListForMerchantDTO> list = mbrStoredStreamQuery.searchStoredListMerchantAll(condition);
                listScoreExcel = CJBeanUtils.convertCollection(list, ScoreFormDetailListResponse.class);
            }
        } else {
            PagingResult<StoredDetailListForMerchantDTO> dtoPagingResult = mbrStoredStreamQuery.searchStoredListMerchant(condition);
            listScoreExcel = CJBeanUtils.convertCollection(dtoPagingResult.getItems(), ScoreFormDetailListResponse.class);
        }

        return listScoreExcel;
    }

    /**
     * 储值明细报表，金额统计--商户权限
     *
     * @param session 获取用户信息session
     * @return 金额统计
     * @map storedAmount
     * @see StoredAmountResponse
     */
    @RequestMapping(value = "/searchStoredAmount")
    @Login
    public Response searchStoredAmount(@RequestBody @Validated QueryStoredRequest request, HttpSession session) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryStoredCondition queryStoredCondition = new QueryStoredCondition();
        queryStoredCondition.setMerchantId(user.getMerchantId());
        queryStoredCondition.setStartTime(request.getStartTime());
        queryStoredCondition.setEndTime(request.getEndTime());
        queryStoredCondition.setMobile(request.getMobile());
        queryStoredCondition.setPayTerminal(request.getPayTerminal());
        queryStoredCondition.setType(request.getType());

        StoredAmountDTO dto = mbrStoredStreamQuery.searchStoredAmount(queryStoredCondition);
        StoredAmountResponse response = new StoredAmountResponse();
        CJBeanUtils.convertBean(dto, response);
        return ResponseUtils.success("storedAmount", response);
    }


    /**
     * 储值明细报表，金额统计--门店权限
     *
     * @return 金额统计
     * @map storedAmount
     * @see StoredAmountResponse
     */
    @RequestMapping(value = "/searchStoredAmountForStore")
    @Login
    public Response searchStoredAmountForStore(@RequestBody @Validated QueryStoredRequest request) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryStoredCondition queryStoredCondition = new QueryStoredCondition();
        queryStoredCondition.setMerchantId(user.getMerchantId());
        queryStoredCondition.setStoreId(user.getStoreId());
        queryStoredCondition.setStartTime(request.getStartTime());
        queryStoredCondition.setEndTime(request.getEndTime());
        queryStoredCondition.setMobile(request.getMobile());
        queryStoredCondition.setPayTerminal(request.getPayTerminal());
        queryStoredCondition.setType(request.getType());

        StoredAmountDTO dto = mbrStoredStreamQuery.searchStoredAmount(queryStoredCondition);
        StoredAmountResponse response = new StoredAmountResponse();
        CJBeanUtils.convertBean(dto, response);
        return ResponseUtils.success("storedAmount", response);
    }

}
